package rgr;

import process.Actor;
import process.DispatcherFinishException;
import process.IWaitCondition;
import queues.Store;
import rnd.Randomable;
//Клас для абстракції Дробарка
public class Drob extends Actor {

	// Посилання на бункер, до якої дробарка нагрібає каміння
	private Store heap;

	// Критична кількість каміння, при якому дробарка припиняє роботу
	private double heapMaxSize;

	// Тривлістьсть роботи дробарки
	private double finishTime;

	// Генератор часу, що витрачає дробарка на одну порцію каміння
	private Randomable rnd;

	//Коструктор, у якому ініціалізуються усі поля класу
	//через доступ до моделі та візуальної частини
	public Drob(String name, GUI gui, Model model) {
		setNameForProtocol(name);
		heap = model.getHeep();
		heapMaxSize = gui.getChooseDataHeepMaxSize().getDouble();
		finishTime = gui.getChooseDataFinishTime().getDouble();
		rnd = gui.getRndBuldo();
	}
	//Правила дії дробарки
	protected void rule() {
		// Умова для методу WaitForConition()
		// Створюється один раз, до основного циклу роботи
		IWaitCondition heapHalfSize = new IWaitCondition() {
			public boolean testCondition() {
				return heap.getSize() <= heapMaxSize / 2;
			}

			public String toString() {
				return ("поки бункер звільниться на половину");
			}
		};
		// Цикл правил дії дробарки
		while (true) {
			// Затримка на час формування порції каміння
			holdForTime(rnd.next());
			// Можливо після цього вже настав час закінчити роботу
			if (getDispatcher().getCurrentTime() > finishTime)
				break;
			// Збільшення розміру купи на одну порцію
			getDispatcher().printToProtocol(
					"  " + getNameForProtocol() + " додає порцію каменів.");
			heap.add(1);
			// Зупинка,якщо купа досягла критичного розміру
			if (heap.getSize() >= heapMaxSize) {
				try {
					waitForCondition(heapHalfSize);
				} catch (DispatcherFinishException e) {
					return;
				}
			}
		}
	}
}
